home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Presentations / Presentations ’91 / MPW Stand-Alone Libraries / UMakeSA.incl.p < prev    next >
Text File  |  1991-06-13  |  8KB  |  316 lines

  1. {--------------------------------------------------------------------------------------------------}
  2.  
  3. {$S TInit}
  4. { Initialize our tool. First initialize the parent, then ourself. }
  5.  
  6. PROCEDURE TMakeSA.IMakeSA;
  7.  
  8.     VAR
  9.         aDynamicArray:    TDynamicArray;
  10.         aString:        StringHandle;
  11.         fi:                FailInfo;
  12.     
  13.     PROCEDURE HdlFailure(error: Integer; message: LongInt);
  14.         BEGIN
  15.             IF (aDynamicArray <> NIL) THEN aDynamicArray.Free;
  16.             IF (aString <> NIL) THEN DisposHandle(Handle(aString));
  17.         END;
  18.  
  19.     BEGIN
  20.         fFileNames := NIL;
  21.         fMainName := NIL;
  22.         
  23.         SELF.ITool;
  24.         
  25.         CatchFailures(fi, HdlFailure);
  26.         aDynamicArray := NIL;
  27.         New(aDynamicArray);
  28.         FailNil(aDynamicArray);
  29.         aDynamicArray.IDynamicArray(0, SizeOf(FileSpec));
  30.         fFileNames := aDynamicArray;
  31.         
  32.         fFileType := kDfltFileType;
  33.         fFileCreator := kDfltFileCreator;
  34.         fMainType := kDfltMainSeg;
  35.         fMainID := kDfltRsrcID;
  36.         
  37.         aString := NIL;
  38.         aString := StringHandle(NewHandle(SIZEOF(STR255)));
  39.         FailNil(aString);
  40.         fMainName := aString;
  41.         fMainName^^[0] := CHR(0);    { Set it to empty string }
  42.         
  43.         fDoMultiSeg := FALSE;
  44.         fOtherSegsType := kDfltOtherSeg;
  45.         
  46.         Success(fi);
  47.     END;
  48.  
  49. {--------------------------------------------------------------------------------------------------}
  50.  
  51. {$S TInit}
  52. { Whenever the option '-help' is found, the tool calls this method }
  53. { to display the syntax on how to use the tool. }
  54.  
  55. PROCEDURE TMakeSA.DoShowUsage; OVERRIDE;
  56.  
  57.     PROCEDURE HelpLine(theStr: Str255);
  58.         BEGIN
  59.             WriteLn(Diagnostic, theStr);
  60.         END;
  61.     
  62.     BEGIN
  63.         HelpLine('MakeSA         # Software Ventures'' stand alone code tool');
  64.         HelpLine('MakeSA [option…] [file…] ≥ progress');
  65.         HelpLine('  -ct type     # Set resource type of non-main code segments  (default = DUDE)');
  66.         HelpLine('  -fc type     # Set file type of output file                 (default = rsrc)');
  67.         HelpLine('  -ft creator  # Set file creator of output file              (default = RSED)');
  68.         HelpLine('  -help        # Return this help text');
  69.         HelpLine('  -id integer  # Set the resource id of the main segment      (default = 128)');
  70.         HelpLine('  -mn name     # Set the resource name of the main segment    (default = '''')');
  71.         HelpLine('  -mt type     # Set the resource type of the main segment    (default = DUDE)');
  72. {
  73.         HelpLine('  -o filename  # Name of the output file                      (default = input.dude)');
  74. }
  75.         HelpLine('  -[No]P       # Report progress                              (default = NoP)');
  76.         HelpLine('  -[No]S       # Allow multi-segmented stand alone code       (default = NoS)');
  77.         HelpLine('  -[No]T       # Report elapsed time                          (default = NoT)');
  78.     END;
  79.  
  80. {--------------------------------------------------------------------------------------------------}
  81.  
  82. {$S TInit}
  83. { Install our keywords for MakeSA. }
  84.  
  85. PROCEDURE TMakeSA.InstallKeyWords; OVERRIDE;
  86.  
  87.     BEGIN
  88.         INHERITED InstallKeyWords;        { Do the default key words }
  89.         
  90.         InstallKeyWord('CT',    kwCType);
  91.         InstallKeyWord('FC',    kwFCreator);
  92.         InstallKeyWord('FT',    kwFType);
  93.         InstallKeyWord('ID',    kwMID);
  94.         InstallKeyWord('MN',    kwMName);
  95.         InstallKeyWord('MT',    kwMType);
  96.         { InstallKeyWord('O',        kwOut); }    { Not ready to support this yet }
  97.         InstallKeyWord('S',        kwSeg);
  98.         InstallKeyWord('NOS',    kwNoSeg);
  99.     END;
  100.             
  101. {--------------------------------------------------------------------------------------------------}
  102.  
  103. {$S TInit}
  104. { When the parser finds a file name, this routine is called to add it }
  105. { to the list of filenames gathered for proccessing into standalones. }
  106.  
  107. PROCEDURE TMakeSA.DoProcessFileArg(arg: Str255); OVERRIDE;
  108.  
  109.     VAR
  110.         aFile:    FileSpec;
  111.         
  112.     BEGIN
  113.         aFile.fileName := NIL;
  114.         aFile.vRefNum := 0;
  115.         aFile.fileName := NewString(arg);
  116.         FailNil(aFile.fileName);
  117.         fFileNames.InsertElementsBefore(1, @aFile, 1);
  118.     END;
  119.             
  120. {--------------------------------------------------------------------------------------------------}
  121.  
  122. {$S TRes}
  123.  
  124. { Simple little procedure for outputing progress lines }
  125. PROCEDURE TMakeSA.DoShowProgress(aStr: Str255);
  126.  
  127.     VAR
  128.         tempName:    Str255;
  129.         
  130.     BEGIN
  131.         IF fProgress THEN
  132.             BEGIN
  133.                 tempName := fProgName;
  134.                 WriteLn(Diagnostic, kErrorMarker, tempName, ' <<>> ', aStr);
  135.                 WriteLn(Diagnostic, kErrorMarker);
  136.                 PLFlush(Diagnostic);
  137.             END;
  138.     END;
  139.     
  140. {--------------------------------------------------------------------------------------------------}
  141.  
  142. {$S TInit}
  143. { Whenever an option with a '-' in front of it is found, the tool calls }
  144. { this method if the option is found in the list of keywords. We check }
  145. { to see if it's one of ours, and if so call GetNextArg to get the data }
  146. { associated with the option. If the option is not one of ours, we call }
  147. { the parent code to let it handle the option. }
  148.  
  149. PROCEDURE TMakeSA.DoProcessOptionArg(kw: Integer); OVERRIDE;
  150.  
  151.     VAR
  152.         tempStr:    Str255;
  153.         aLong:        LongInt;
  154.         
  155.     BEGIN
  156.         CASE kw OF
  157.             kwFType:
  158.                 BEGIN
  159.                     tempStr := SELF.GetNextArg;
  160.                     IF (length(tempStr) <> 4) THEN
  161.                         SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid file type>'))
  162.                     ELSE
  163.                         BlockMove(@tempStr[1], @fFileType, 4);
  164.                 END;
  165.                 
  166.             kwFCreator:
  167.                 BEGIN
  168.                     tempStr := GetNextArg;
  169.                     IF (length(tempStr) <> 4) THEN
  170.                         SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid file creator>'))
  171.                     ELSE
  172.                         BlockMove(@tempStr[1], @fFileCreator, 4);
  173.                 END;
  174.                 
  175.             kwMType:
  176.                 BEGIN
  177.                     tempStr := GetNextArg;
  178.                     IF (length(tempStr) <> 4) THEN
  179.                         SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid resource type>'))
  180.                     ELSE
  181.                         BlockMove(@tempStr[1], @fMainType, 4);
  182.                 END;
  183.                 
  184.             kwMID:
  185.                 BEGIN
  186.                     tempStr := GetNextArg;
  187.                     StringToNum(tempStr, aLong);
  188.                     IF (aLong > maxInt) OR (aLong < -maxInt-1) THEN
  189.                         SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid resource ID>'))
  190.                     ELSE
  191.                         fMainID := aLong;
  192.                 END;
  193.                 
  194.             kwMName:
  195.                 BEGIN
  196.                     tempStr := GetNextArg;
  197.                     fMainName^^ := tempStr;
  198.                 END;
  199.                 
  200.             kwOut:
  201.                 BEGIN
  202.                     tempStr := GetNextArg;
  203.                     {fOutName^^ := tempStr;}    { not ready to support this yet }
  204.                 END;
  205.                 
  206.             kwCType:
  207.                 BEGIN
  208.                     tempStr := GetNextArg;
  209.                     IF (length(tempStr) <> 4) THEN
  210.                         SyntaxError(Concat(ArgV^[fArgVIndex]^, ' <invalid resource type>'))
  211.                     ELSE
  212.                         BlockMove(@tempStr[1], @fOtherSegsType, 4);
  213.                 END;
  214.                 
  215.             kwSeg:
  216.                 BEGIN
  217.                     fDoMultiSeg := TRUE;
  218.                 END;
  219.                 
  220.             kwNoSeg:
  221.                 BEGIN
  222.                     fDoMultiSeg := FALSE;
  223.                 END;
  224.                 
  225.             OTHERWISE
  226.                 INHERITED DoProcessOptionArg(kw);
  227.         END;
  228.     END;
  229.  
  230. {--------------------------------------------------------------------------------------------------}
  231.  
  232. {$S TRes}
  233. { Given the list of files names, and a procedure to operate on each file }
  234. { walk through the list of files, handing each off to the procedure. }
  235.  
  236. PROCEDURE TMakeSA.ForEachFileDo(PROCEDURE DoToFile(aFile: FileSpec));
  237.  
  238.     VAR
  239.         dummy:    ArrayIndex;
  240.         
  241.     FUNCTION ForThisItemDo(index: ArrayIndex): BOOLEAN;
  242.         
  243.         LABEL 1234;
  244.         VAR
  245.             fi:            FailInfo;
  246.             aFileSpec:    FileSpec;
  247.         
  248.         PROCEDURE HdlFailure(error: Integer; message: LongInt);
  249.             BEGIN
  250.                 IF (error = resFNotFound) OR (error = fnfErr) THEN
  251.                     GOTO 1234;
  252.             END;
  253.             
  254.         BEGIN
  255.             fFileNames.GetElementsAt(index, @aFileSpec, 1);
  256.             CatchFailures(fi, HdlFailure);
  257.             SpinCursor(1);
  258.             DoToFile(aFileSpec);
  259.             Success(fi);
  260.         1234:
  261.             ForThisItemDo := FALSE;
  262.         END;
  263.     
  264.     BEGIN
  265.         dummy := fFileNames.EachElementDoTil(ForThisItemDo, kIterateBackward);
  266.     END;
  267.  
  268. {--------------------------------------------------------------------------------------------------}
  269.  
  270. {$S TRes}
  271. { The Tool calls this method after it has successfully parsed the command line. }
  272. { Now, for each file found, massage it into a stand alone piece of code. }
  273.  
  274. PROCEDURE TMakeSA.DoToolAction; OVERRIDE;
  275.  
  276.     VAR
  277.         aFile:        FileSpec;
  278.     
  279.     PROCEDURE SingleSegMassage(aFile: FileSpec);
  280.         
  281.         VAR
  282.             aBuildSA:    TSingleSegSA;
  283.         BEGIN
  284.             New(aBuildSA);
  285.             FailNIL(aBuildSA);
  286.             aBuildSA.ISingleSegSA(aFile, fMainType, fMainID, fMainName);
  287.             aBuildSA.DoIt;
  288.             aBuildSA.Free;
  289.         END;
  290.         
  291.     PROCEDURE MultiSegMassage(aFile: FileSpec);
  292.         
  293.         VAR
  294.             aBuildSA:    TMultiSegSA;
  295.         BEGIN
  296.             New(aBuildSA);
  297.             FailNIL(aBuildSA);
  298.             aBuildSA.IMultiSegSA(aFile, fMainType, fMainID, fMainName, fOtherSegsType);
  299.             aBuildSA.DoIt;
  300.             aBuildSA.Free;
  301.         END;
  302.         
  303.     BEGIN
  304.         IF (fFileNames.IsEmpty) THEN
  305.             BEGIN
  306.                 fRetCode := RC_ParmErrs;
  307.                 Stop('No files to operate on.');
  308.             END
  309.         ELSE IF (NOT fDoMultiSeg) THEN
  310.             ForEachFileDo(SingleSegMassage)
  311.         ELSE
  312.             ForEachFileDo(MultiSegMassage);
  313.     END;
  314.             
  315. {--------------------------------------------------------------------------------------------------}
  316.